/* eslint-disable */
import moment from 'moment';
import { parse } from 'qs';
import _ from 'lodash';
import pathToRegexp from 'path-to-regexp/index';
import html2canvas from 'html2canvas';

// 获取内容长度，getColumnIntoWidth用
export function getTextWidth(text, font = '14px Microsoft YaHei') {
  const canvas = document.createElement('canvas');
  let context = canvas.getContext('2d');
  context.font = font;
  let textmetrics = context.measureText(text);
  return textmetrics.width;
}

/**
 * 自动计算column的width与内容长度取最大值
 * @param columns
 * @param data
 * @returns {*}
 */
export function getColumnIntoWidth(columns, data) {
  let widthMap = new Map();
  // columns 为动态表格的表头数组 data为展示数据的数组
  //作用是遍历所有数据拿到长度最长的一条记下他的宽度
  data.forEach((target) => {
    for (let key in target) {
      if (target.hasOwnProperty(key)) {
        // 如果是数组， 取最长的value
        if (Object.prototype.toString.call(target[key]) === '[object Array]') {
          let max = getTextWidth(target[key][0]);
          for (let i = 1; i < target[key].length; i++) {
            const cur = getTextWidth(target[key][i]);
            cur > max ? (max = cur) : null;
          }
          const currentValue = widthMap.get(key);
          widthMap.set(key, Math.max(currentValue ?? 0, max));
        } else {
          const keyWidth = getTextWidth(target[key]);
          const currentValue = widthMap.get(key);
          widthMap.set(key, Math.max(currentValue ?? 0, keyWidth));
        }
      }
    }
  });

  const copyColumn = _.cloneDeep(columns);
  copyColumn.map((item) => {
    // title，dataIndex为 ant design Table对应参数
    const textWidth = getTextWidth(item.title);
    if ((widthMap.get(item.dataIndex) ?? 0) < textWidth) {
      widthMap.set(item.dataIndex, textWidth);
    }
    let width;
    if (item.width) {
      width = item.width;
    } else {
      width = isNaN(Math.ceil(widthMap.get(item.dataIndex)) + 35) ? 120 : Math.ceil(widthMap.get(item.dataIndex)) + 30;
    }
    return (item.width = width);
  });
  return copyColumn;
}

//获取DPI
export function getDPI() {
  const arrDPI = new Array();
  if (window.screen.deviceXDPI != undefined) {
    arrDPI[0] = window.screen.deviceXDPI;
    arrDPI[1] = window.screen.deviceYDPI;
  } else {
    const tmpNode = document.createElement('DIV');
    tmpNode.style.cssText = 'width:1in;height:1in;position:absolute;left:0px;top:0px;z-index:99;visibility:hidden';
    document.body.appendChild(tmpNode);
    arrDPI[0] = parseInt(tmpNode.offsetWidth);
    arrDPI[1] = parseInt(tmpNode.offsetHeight);
    tmpNode.parentNode.removeChild(tmpNode);
  }
  return arrDPI;
}
export function base64ToBlob(urlData) {
  try {
    const arr = urlData.split(',');
    const mime = arr[0].match(/:(.*?);/)[1] || 'image/png';
    const bytes = window.atob(arr[1]);
    const ab = new ArrayBuffer(bytes.length);
    const ia = new Uint8Array(ab);
    for (let i = 0; i < bytes.length; i++) {
      ia[i] = bytes.charCodeAt(i);
    }
    return new Blob([ab], {
      type: mime,
    });
  } catch (e) {
    const ab = new ArrayBuffer(0);
    return new Blob([ab], {
      type: 'image/png',
    });
  }
}

/***
 * @desc dom元素转图片url 返回的是Promise对象
 * @desc 选项当前设备dpi-96 {dpi：96}={scale：1}，并且任何选项的更大值都将提高分辨率。
 * @desc 最好设置dom元素的内联宽高
 * @param domElement dom元素对象
 * @param canvasDep {{scale: number}}
 * @param base64OrBlob {boolean}
 * @returns {Promise<string>}
 */
export async function domElementToImageUrl(domElement, canvasDep = { scale: 1, dpi: 96 }, base64OrBlob = true) {
  return await html2canvas(domElement, canvasDep).then(function (canvas) {
    let img = canvas.toDataURL('image/png').replace('image/png', 'image/octet-stream');
    if (base64OrBlob) {
      return img;
    }
    if (!base64OrBlob) {
      const blob = base64ToBlob(img);
      return URL.createObjectURL(blob);
    }
  });
}

// 补0
export function fixedZero(val) {
  let value = val * 1;
  if (value % 1 == 0 && value > 0) {
    value = value < 10 ? `0${val}` : val;
    return value;
  }
}

/***
 * @param num 原值-需要补0的值
 * @param n 代表输出几位数
 * @returns {String}
 */
export const fixedZeroNum = (function () {
  //数字补0 n代表几位数
  var tbl = [];
  return function (num, n) {
    var len = n - num.toString().length;
    if (len <= 0) return num;
    if (!tbl[len]) tbl[len] = new Array(len + 1).join('0');
    return tbl[len] + num;
  };
})();

/***
 * @desc 将字符串日期转换成moment对象
 * @param val 字符串日期
 * @returns {String}
 */
export function setFormTime(val) {
  return val ? moment(val) : null;
}

/***
 * @desc 判断地址规范是否正确
 * @param path 地址
 * @returns {String}
 */
export function isUrl(path) {
  /* eslint no-useless-escape:0 */
  const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/g;
  return reg.test(path);
}

/**
 * 千分位展示
 * @param {*} num
 * @param {boolean} bit 保留小数位
 * @returns {String}
 */

export function fixedNum(num, bit = 2) {
  if (num == 0 || !num || num == undefined || num == null || num == '--') {
    let val = '0.';
    for (let i = 0; i < bit; i++) {
      val = val + '0';
    }
    return val;
  }
  let param = num;
  if (typeof param === 'string') {
    param = Number(num);
  }
  if (typeof param === 'number') {
    param = parseFloat((param + '').replace(/[^\d\.-]/g, '')).toFixed(bit) + '';
  }
  return param;
}

/***
 * @desc 根据key从dataSource中找到某个object
 * @param key 需要处理的key值
 * @param dataSource dataSource数据源
 * @returns {Object}
 */
export function findItemByKey(key, dataSource) {
  let result = {};
  const func = (key, dataSource) => {
    for (let item of dataSource) {
      if (item.key === key) {
        result = item;
      } else {
        if (item.children) {
          func(key, item.children);
        }
      }
    }
  };
  func(key, dataSource);
  return result;
}

/***
 * @desc 根据key从dataSource中删除某个object
 * @param key 需要处理的key值
 * @param dataSource dataSource数据源
 * @returns {array}
 */
export function deleteItemByKey(key, dataSource) {
  func(key, dataSource);
  function func(key, dataSource) {
    for (let i = 0; i < dataSource.length; i++) {
      if (dataSource[i].key === key) {
        dataSource.splice(i, 1);
      }
      if (dataSource[i] && dataSource[i].children && dataSource[i].children.length !== 0) {
        func(key, dataSource[i].children);
      }
    }
  }
  return dataSource;
}

//数组深度拷贝
export function depCopy(dataSource) {
  return JSON.parse(JSON.stringify(dataSource));
}

//根据数据字典的code寻找Value
export function findValueByCode(code, jsonData) {
  let result = null;
  if (code && jsonData) {
    const obj = jsonData.filter((item) => {
      return item.code === code;
    });
    if (obj.length !== 0) {
      result = obj[0].value;
    }
  }
  return result || '--';
}

/***
 * @desc 根据数据字典 返回下拉数组
 * @param jsonData 字典值
 * @returns {array}
 */
export function formSelectData(jsonData) {
  let arr = [];
  if (jsonData) {
    jsonData.map((item) => {
      arr.push({
        value: item.code,
        title: item.value,
      });
    });
  }
  return arr;
}

/***
 * @desc 根据数据字典 返回下拉数组
 * @param arr 字典值
 * @returns {array}
 */
export function formatDictData(arr = []) {
  let temp = [];
  if (!arr) return temp;
  arr.map((item) => {
    temp.push({
      title: item.keyDesc,
      value: item.value,
    });
  });
  return temp;
}

/***
 * @desc  根据key查询名称title
 * @param value key值
 * @param jsonData 数据源
 * @returns {string}
 */
export function findTitleByValue(value, jsonData) {
  let result = null;
  if (value && jsonData) {
    const obj = jsonData.filter((item) => {
      return item.value === value;
    });
    if (obj.length !== 0) {
      result = obj[0].title;
    }
  }
  return result || '--';
}

/***
 * @desc  优化菜单数据--处理菜单路径/权限
 * @param data 菜单数据
 * @param parentPath 父级菜单路径
 * @param parentAuthority 父级菜单权限
 * @returns {Array}
 */
export function menuDataFormat(data, parentPath = '/') {
  return data.map((item) => {
    let { path } = item;
    if (!isUrl(path)) {
      path = parentPath + item.path;
    }
    const result = {
      ...item,
      path,
      // authority: item.authority || parentAuthority, 这个字段无效 去掉
    };
    if (item.menuModels) {
      result.menuModels = menuDataFormat(item.menuModels, `${parentPath}${item.path}/`);
    }
    return result;
  });
}

// 获取最新的id，该id从data源中找到pid相同的row。并且找到row中最大的id
export function getLastId(pid, data) {
  let result = Number(pid + 0);
  function pushId(pid, data) {
    for (let item of data) {
      if (item.id && item.pid === pid) {
        if (Number(item.id) > result) {
          result = Number(item.id);
        }
      }
      if (item.children) {
        pushId(pid, item.children);
      }
    }
  }
  pushId(pid, data);
  return result;
}

//data转换
export function switchData(dataDt) {
  return `${dataDt.substring(0, 4)}-${dataDt.substring(4, 6)}-${dataDt.substring(6, 8)}`;
}

// menu 数据格式改造
export function switchMenu(dataSource) {
  function switchData(dataSource) {
    for (let item of dataSource) {
      item.key = item.id;
      item.value = item.id;
      item.label = item.name;
      item.roleIdsArr = [];
      if (item.roleIds.length !== 0) {
        for (let i of item.roleIds) {
          item.roleIdsArr.push(i.roleId);
        }
      }
      if (item.children.length === 0) {
        delete item.children;
      } else {
        switchData(item.children);
      }
    }
  }
  switchData(dataSource);
  return dataSource;
}

/***
 * @desc  根据id查询菜单名称name
 * @param id
 * @param dataSource 菜单列表
 * @returns {string}
 */
export function findNameById(id, dataSource) {
  let rs = '';
  func(id, dataSource);
  function func(id, dataSource) {
    for (let item of dataSource) {
      if (item.id === id) {
        rs = item.name;
      }
      if (item.children && item.children.length !== 0) {
        func(id, item.children);
      }
    }
  }
  return rs;
}

/***
 * @desc  菜单数据及子菜单按优先级排序
 * @param menuData 菜单列表
 * @returns {Array}
 */
export function MenuSort(menuData) {
  if (!(menuData && menuData[0])) return [];
  if (!_.isNil(menuData[0].priority)) {
    for (var i = 0; i < menuData.length; i++) {
      menuData[i].children = menuData[i].children == '' ? '' : MenuSort(menuData[i].children);
    }
  }
  return menuData;
}
// 将children模式的menuData转化为一维的形式
export function getFlatMenuData(menus) {
  let keys = {};
  menus.forEach((item) => {
    if (item.menuModels) {
      keys[item.path] = { ...item };
      keys = { ...keys, ...getFlatMenuData(item.menuModels) };
    } else {
      keys[item.path] = { ...item };
    }
  });
  return keys;
}

function flattenRoutes(routeDatas) {
  let result = [];
  for (let route of routeDatas) {
    const { routes, ...rest } = route;
    // if (rest.path !== '/') {
    result.push(rest);
    // }
    if (routes && routes.length) {
      result = result.concat(flattenRoutes(routes));
    }
  }
  return result;
}

//
/***
 * @desc  组合routerData和后台获取的menuData形成最新的routerData
 * @param menuData 菜单列表
 * @returns {Array}
 */
export function combineData(routerData, menuData) {
  const flatMenuData = getFlatMenuData(menuDataFormat(menuData));
  const rsRouterData = {};
  // Object.keys(routerData).forEach((path) => {
  flattenRoutes(routerData).forEach((item) => {
    const path = item.path;
    if (path === '/') {
      return;
    }
    const pathRegexp = pathToRegexp(path);
    const menuKey = Object.keys(flatMenuData).find((key) => pathRegexp.test(`${key}`));
    let menuItem = {};
    if (menuKey) {
      menuItem = flatMenuData[menuKey];
    }
    // let router = routerData[path];
    let router = item;
    router = {
      ...router,
      // name: menuItem.name || router.name,
      name: menuItem.name || menuItem.title || router.name || router.title,
      // authority: router.authority || menuItem.authority, 无具体使用 去掉
      // operateType: menuItem.operateType || 'view', 无具体使用 去掉
      icon: menuItem.icon,
    };
    rsRouterData[path] = router;
  });
  return rsRouterData;
}

//根据id或者value找到对应的单个元素
export function getTreebyKey(tree, key) {
  let res;
  for (var i = 0; i < tree.length; i++) {
    if (tree[i].id == key || tree[i].value == key) {
      return tree[i];
    } else {
      if (tree[i].children) {
        const res = getTreebyKey(tree[i].children, key);
        if (res) {
          return res;
        }
      }
    }
  }
}
//计算月日历展示第一天 出参是moment格式
export function getMonthFirstDay(date) {
  if (moment(moment(date).format('YYYY-MM') + '-01').format('d') == 0) {
    //第一天为周日
    return moment(moment(date).format('YYYY-MM') + '-02');
  } else if (moment(moment(date).format('YYYY-MM') + '-01').format('d') == 6) {
    //第一天为周六
    return moment(moment(date).format('YYYY-MM') + '-03');
  } else {
    return moment(moment(date).format('YYYY-MM') + '-01');
  }
}
//组合树 树形结构 简化成新的结构  只保留 name value
export const getTreeList = (treeList, newTreeList) => {
  treeList.map((c) => {
    let tempData = {
      name: c.name,
      value: c.value,
    };
    if (c.children && c.children.length > 0) {
      tempData.children = [];
      getTreeList(c.children, tempData.children);
    }
    newTreeList.push(tempData);
  });
};
//产品组根据value 获取name
export function getProductName(value, data) {
  let name;
  if (data && data.length) {
    data.map((item) => {
      if (item.value == value) {
        name = item.title;
      }
    });
  }
  return name;
}

//查找数组是否重复
export function isRepeat(arr) {
  var hash = {};
  for (var i in arr) {
    if (hash[arr[i]]) return true;
    hash[arr[i]] = true;
  }
  return false;
}

// 判断一个数组是否包含另一个数组
export function isContainArr(parent, child) {
  return child.every((item) => {
    return parent.some((v) => {
      return item == v;
    });
  });
}
// 判断一个数组是否包含另一个数组的某一项
export function isContainArrOne(parent, child) {
  if (parent && child) return !!parent.find((i) => child.includes(i));
  return false;
}

// 待处理/待删除

// 控制只能输入数字
export function inputOnlyNumber(e) {
  e.target.value = e.target.value.replace(/[^\-?\d.]/g, '');
}
